package com.xyzwps.webfluxjava.handler;

import com.xyzwps.webfluxjava.handler.demo.DemoFilters;
import com.xyzwps.webfluxjava.handler.demo.DemoHandlers;
import lombok.val;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.reactive.function.server.RouterFunction;
import org.springframework.web.reactive.function.server.ServerResponse;

import static org.springframework.web.reactive.function.server.RouterFunctions.route;
import static org.springframework.web.reactive.function.server.RouterFunctions.nest;
import static org.springframework.web.reactive.function.server.RequestPredicates.GET;
import static org.springframework.web.reactive.function.server.RequestPredicates.POST;
import static org.springframework.web.reactive.function.server.RequestPredicates.path;
import static org.springframework.web.reactive.function.server.RequestPredicates.accept;
import static org.springframework.http.MediaType.APPLICATION_JSON_UTF8;
import static org.springframework.http.MediaType.APPLICATION_JSON;

@Configuration
public class RoutersConfig {

    @Autowired
    private DemoHandlers demoHandlers;

    @Autowired
    private PageCommonHandlers pageCommonHandlers;

    @Autowired
    private DemoFilters demoFilters;

    @Bean
    public RouterFunction<ServerResponse> demoRouters() {

        val nestRoutes = route(GET("/n-1"), demoHandlers::getJSON)
                .andRoute(GET("/n-2"), demoHandlers::getJSON);

        // 这里的顺序是 filter2 -> filter1 -> emoHandlers::forfilters
        val filterRoutes = route(GET("/filters"), demoHandlers::forfilters)
                .filter(demoFilters::filter1).filter(demoFilters::filter2);

        return route(GET("/json"), demoHandlers::getJSON)
                .and(route(GET("/path-vars/{id}"), demoHandlers::pathVars))
                .and(nest(path("/nest"), nestRoutes))
                .and(filterRoutes)
                .andRoute(POST("/post").and(accept(APPLICATION_JSON_UTF8)), demoHandlers::post)
                .andRoute(POST("/async").and(accept(APPLICATION_JSON)), demoHandlers::async)
                .andRoute(POST("/parallel").and(accept(APPLICATION_JSON)), demoHandlers::parallelAsync)
                .and(route(GET("/except"), demoHandlers::except))
                .and(route(GET("/serial"), demoHandlers::respSerial))
                .and(route(GET("/mysql/{uniqId}"), demoHandlers::mysql));
    }

    @Bean
    public RouterFunction<ServerResponse> routers() {
        return route(GET("/"), pageCommonHandlers::index)
                .andRoute(GET("/home"), pageCommonHandlers::home)
                .andNest(path("/demo"), demoRouters());
    }

}
